#ifndef __LIST_H__
#define __LIST_H__

#include <stdio.h>
#include <stdint.h>

// 定义节点结构
typedef struct _Node
{
    void *data;
    struct _Node *prev;
    struct _Node *next;
} _Node;

// 定义双向链表结构
typedef struct _DoublyLinkedList
{
    _Node *head;
    _Node *tail;
    int length;
} _DoublyLinkedList;

// 构造链表类
typedef struct DoublyLinkedListObjct
{
    _DoublyLinkedList list;
    // 创建链表，不开放
    //  void (*create)(struct DoublyLinkedListObjct *obj);
    /**
     * @brief 向双向链表对象的末尾添加一个新节点。
     *
     * 该函数指针指向的函数用于将一个新的数据元素添加到双向链表对象的末尾。
     *
     * @param obj 指向双向链表对象的指针。
     * @param data 指向要添加的数据的指针，需要转换成void*类型。
     */
    void (*push_back)(struct DoublyLinkedListObjct *obj, void *data);
    /**
     * @brief 向双向链表对象的头部添加一个新节点。
     *
     * 该函数指针指向的函数用于将一个新的数据元素添加到双向链表对象的末尾。
     *
     * @param obj 指向双向链表对象的指针。
     * @param data 指向要添加的数据的指针，需要转换成void*类型。
     */
    void (*push_front)(struct DoublyLinkedListObjct *obj, void *data);
    /**
     * @brief 从双向链表对象的末尾移除一个节点，并返回该节点的数据。
     *
     * 该函数指针指向的函数用于从双向链表对象的末尾移除一个节点，并返回该节点所包含的数据。
     * 如果链表为空，则返回NULL。
     *
     * @param obj 指向双向链表对象的指针。
     * @return 指向被移除节点的数据的指针，如果链表为空则返回NULL。
     */
    void *(*pop_back)(struct DoublyLinkedListObjct *obj);
    /**
     * @brief 从双向链表对象的开头移除一个节点，并返回该节点的数据。
     *
     * 该函数指针指向的函数用于从双向链表对象的开头移除一个节点，并返回该节点所包含的数据。
     * 如果链表为空，则返回NULL。
     *
     * @param obj 指向双向链表对象的指针。
     * @return 指向被移除节点的数据的指针，如果链表为空则返回NULL。
     */
    void *(*pop_front)(struct DoublyLinkedListObjct *obj);

    /**
     * @brief 获取双向链表中指定位置的数据。
     *
     * 该函数用于获取双向链表中指定位置的数据。如果索引越界，则返回NULL。
     *
     * @param obj 指向双向链表对象的指针。
     * @param index 要获取的数据的索引位置。
     * @return 指向指定位置数据的指针，如果索引越界则返回NULL。
     */
    void *(*get)(struct DoublyLinkedListObjct *obj, int index);

    /**
     * @brief 在双向链表的指定位置插入一个新节点。
     *
     * 该函数用于在双向链表的指定位置插入一个新节点，包含指定的数据。
     * 如果索引越界，则不进行插入操作。
     *
     * @param obj 指向双向链表对象的指针。
     * @param index 要插入新节点位置的索引。
     * @param data 指向要插入的数据的指针。
     */
    void (*insert)(struct DoublyLinkedListObjct *obj, int index, void *data);

    /**
     * @brief 从双向链表中移除指定位置的节点。
     *
     * 该函数用于从双向链表中移除指定位置的节点。如果索引越界，则不进行移除操作。
     *
     * @param obj 指向双向链表对象的指针。
     * @param index 要移除节点的索引位置。
     */
    void (*remove)(struct DoublyLinkedListObjct *obj, int index);

    /**
     * @brief 清空双向链表中的所有节点。
     *
     * 该函数用于清空双向链表中的所有节点，释放所有节点所占用的内存。
     *
     * @param obj 指向双向链表对象的指针。
     */
    void (*clear)(struct DoublyLinkedListObjct *obj);

    /**
     * @brief 获取双向链表的长度。
     *
     * 该函数用于获取双向链表中节点的数量。
     *
     * @param obj 指向双向链表对象的指针。
     * @return 双向链表中节点的数量。
     */
    int (*length)(struct DoublyLinkedListObjct *obj);

    /**
     * @brief 动态分配内存并初始化数据。
     *
     * 该函数用于创建一个数据对象，并直接转换成void*类型返回，方便将不同类型数据放入链表。
     *
     * @param data 指向要复制的数据的指针。
     * @param size 要分配的内存大小（以字节为单位）。
     * @return 指向分配的内存的指针，如果内存分配失败则返回NULL。
     */
    void *(*lmalloc)(void *data, int size);

} DoublyLinkedListObjct;

void createDoublyLinkedListObjct(DoublyLinkedListObjct *l_obj);

#endif // __LIST_H__
